import Browser from './browser'


const isHtmlElement = function (printable) {
    return typeof printable === 'object' && printable && (printable instanceof HTMLElement)
}

const cleanUp = function (params) {



    let event = 'mouseover'

    if (Browser.isChrome() || Browser.isFirefox()) {
        event = 'focus'
    }

    const handler = () => {
        window.removeEventListener(event, handler)


        const iframe = document.getElementById(params.frameId)

        if (iframe) {
            if (params.frameRemoveDelay) {
                setTimeout(() => {
                    iframe.remove()
                },
                    params.frameRemoveDelay
                )
            } else {
                iframe.remove()
            }
        }
    }

    window.addEventListener(event, handler)
}

const cloneElement = function (element) {
    const clone = element.cloneNode()

    const childNodesArray = Array.prototype.slice.call(element.childNodes)
    for (let i = 0; i < childNodesArray.length; i++) {

        const clonedChild = cloneElement(childNodesArray[i])

        clone.appendChild(clonedChild)
    }
    switch (element.tagName) {
        case 'SELECT':
            clone.value = element.value
            break
        case 'CANVAS':
            clone.getContext('2d').drawImage(element, 0, 0)
            break
    }

    return clone
}


const performPrint = function (iframeElement, params) {
    try {
        iframeElement.focus()

        if (Browser.isEdge() || Browser.isIE()) {
            try {
                iframeElement.contentWindow.document.execCommand('print', false, null)
            } catch (e) {
                setTimeout(function () {
                    iframeElement.contentWindow.print()
                }, 1000)
            }
        } else {
            setTimeout(function () {
                iframeElement.contentWindow.print()
            }, 1000)
        }
    } catch (error) {
        params.onError(error)
    } finally {
        if (Browser.isFirefox() && Browser.getFirefoxMajorVersion() < 110) {
            iframeElement.style.visibility = 'hidden'
            iframeElement.style.left = '-1px'
        }
        cleanUp(params)
    }
}


export function htmlPrint(params) {
    params = Object.assign({
        frameId: 'printJS',
        documentTitle: 'Document'
    }, params)

    let iframeElement = document.createElement('iframe')

    if (Browser.isFirefox()) {
        iframeElement.setAttribute('style', 'width: 1px; height: 100px; position: fixed; left: 0; top: 0; opacity: 0; border-width: 0; margin: 0; padding: 0')
    } else {
        iframeElement.setAttribute('style', 'visibility: hidden; height: 0; width: 0; position: absolute; border: 0')
    }

    iframeElement.setAttribute('id', params.frameId)

    iframeElement.srcdoc = '<html><head><title>' + params.documentTitle + '</title></head><body></body></html>'

    document.getElementsByTagName('body')[0].appendChild(iframeElement)


    let printElement = isHtmlElement(params.printable) ? params.printable : document.getElementById(params.printable)
    let printableElement = cloneElement(printElement)


    iframeElement.onload = () => {
        let printDocument = (iframeElement.contentWindow || iframeElement.contentDocument)
        if (printDocument.document) printDocument = printDocument.document

        printDocument.body.appendChild(printableElement)

        if (params.style) {
            let style = document.createElement('style')
            style.innerHTML = params.style
            printDocument.head.appendChild(style)
        }

        document.head.querySelectorAll('style[data-pagedjs-inserted-styles="true"]').forEach(style => {
            printDocument.head.appendChild(cloneElement(style))
        })

        performPrint(iframeElement, params)
    }

}